package com.xxx.yuedong.community.service.impl;

import com.xxx.yuedong.common.exception.YuedongException;
import com.xxx.yuedong.community.controller.form.CommentDetailForm;
import com.xxx.yuedong.community.db.dao.CommentDao;
import com.xxx.yuedong.community.pojo.Comment;
import com.xxx.yuedong.community.service.CommentService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class CommentServiceImpl implements CommentService {

    @Autowired
    CommentDao commentDao;

    @Override
    public void insert(Comment comment) {
        log.debug("开始处理【新增评论】的业务，参数：{}", comment);
        commentDao.insert(comment);
    }

    @Override
    public void deleteById(Long id) {
        log.debug("开始处理【根据ID删除评论】的业务，参数：{}", id);
        CommentDetailForm currentComment = commentDao.getCommentById(id);
        if (currentComment == null) {
            String message = "删除评论失败，尝试删除的评论数据不存在！";
            log.warn(message);
            throw new YuedongException(404, message);
        }
        recursivelyDeleteCommentAndReplies(currentComment);
    }

    /**
     * 递归遍历评论的回复列表，删除评论及其所有嵌套的回复
     * @param comment 评论
     */
    private void recursivelyDeleteCommentAndReplies(CommentDetailForm comment) {
        // 查询回复的评论
        List<CommentDetailForm> currentReplies = commentDao.getCommentByParentId(comment.getId());
        List<CommentDetailForm> commentReplies = new ArrayList<>(currentReplies);
        comment.setReplies(commentReplies);

        List<CommentDetailForm> replies = comment.getReplies();
        if (replies != null) {
            for (CommentDetailForm reply : replies) {
                recursivelyDeleteCommentAndReplies(reply);
            }
        }
        commentDao.deleteById(comment.getId());
    }

    @Override
    public void update(Comment comment) {
        log.debug("开始处理【根据ID修改评论】的业务，参数：{}", comment);
        commentDao.update(comment);
    }

    @Override
    public CommentDetailForm getCommentById(Long id) {
        log.debug("开始处理【根据ID查询评论】的业务，参数：{}", id);
        return commentDao.getCommentById(id);
    }

    @Override
    public List<CommentDetailForm> listByBuildTree(Long dynamicId) {
        log.debug("开始处理【根据动态ID查看分级评论】的业务，参数：{}", dynamicId);

        // 平铺的评论列表
        List<CommentDetailForm> flatComments = commentDao.listByDynamicId(dynamicId);

        return buildTree(flatComments);
    }

    @Override
    public HashMap getCommentByDynamicId(Long id, Long userId, Long parentId) {
        HashMap comment = commentDao.getCommentByDynamicId(id, userId, parentId);
        return comment;
    }

    /**
     * 构建评论树
     * @param flatComments
     * @return
     */
    public List<CommentDetailForm> buildTree(List<CommentDetailForm> flatComments) {
        List<CommentDetailForm> topLevelComments = new ArrayList<>();
        // 构建一个以id为键，评论对象为值的Map，以便根据parentId查找评论
        MultiValueMap<Long, CommentDetailForm> commentMap = new LinkedMultiValueMap<>();
        for (CommentDetailForm comment : flatComments) {
            commentMap.add(comment.getParentId(), comment);
        }

        for (CommentDetailForm comment : flatComments) {
            if (comment.getParentId() == 0L) { // 找到顶级评论
                CommentDetailForm commentWithReplies = buildTreeRecursively(comment, commentMap);
                topLevelComments.add(commentWithReplies);
            }
        }

        return topLevelComments;
    }

    /**
     * 遍历每个回复，递归地调用 buildTreeRecursively 方法来构建每个回复的评论树，并将它们添加到当前评论的 replies 属性中。
     * @param comment
     * @param commentMap
     * @return
     */
    private static CommentDetailForm buildTreeRecursively(CommentDetailForm comment, MultiValueMap<Long, CommentDetailForm> commentMap) {
        List<CommentDetailForm> replies = commentMap.get(comment.getId());
        if (replies != null) { // 找到回复
            List<CommentDetailForm> commentReplies = new ArrayList<>();
            for (CommentDetailForm reply : replies) {
                CommentDetailForm replyWithReplies = buildTreeRecursively(reply, commentMap);
                commentReplies.add(replyWithReplies);
            }
            comment.setReplies(commentReplies);
        }
        return comment;
    }
}

